package com.cti.commons.mqtt.handle;

import java.util.List;

import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttAsyncClient;
import org.eclipse.paho.client.mqttv3.MqttCallbackExtended;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.MqttTopic;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;

import com.cti.commons.mqtt.domain.ShareMode;
import com.cti.commons.mqtt.domain.SubscriptTopic;

/**
 * mqtt回调处理
 */
public class MqttCallback implements MqttCallbackExtended {

    private static final Logger log = LoggerFactory.getLogger(MqttCallback.class);

    private static final long RETRY_TIME = 1000;

    private List<SubscriptTopic> topics;

    public MqttCallback(List<SubscriptTopic> topics) {
        this.topics = topics;
    }

    @Override
    public void connectionLost(Throwable throwable) {
    }

    @Override
    public void messageArrived(String topic, MqttMessage message) throws Exception {
        for (SubscriptTopic subscriptTopic : topics) {
            if (isMatched(subscriptTopic.getTopic(), topic)) {
                subscriptTopic.getMessageListener().messageArrived(topic, message);
            }
        }
    }

    private boolean isMatched(String topicFilter, String topic) {
        return MqttTopic.isMatched(topicFilter, topic);
    }

    @Override
    public void deliveryComplete(IMqttDeliveryToken token) {

    }

    @Override
    public void connectComplete(boolean reconnect, String serverURI) {
        MqttAsyncClient client = ApplicationContextUtil.getBean(MqttAsyncClient.class);
        //重连回调
        if (reconnect) {
            //todo
        } else {
            //初始化连接首次回调
            if (client.isConnected()) {
                subscribeTopic(client);
            }
        }
    }

    private void subscribeTopic(MqttAsyncClient client) {
        if (CollectionUtils.isEmpty(this.topics)) {
            log.info("mqtt 订阅的主题为空");
            return;
        }
        topics.stream().forEach(it -> {
                String topic = it.getTopic();
                try {
                    if (ShareMode.SHARE.equals(it.getShareMode())) {
                        topic = it.getShareTopic();
                    }
                    client.subscribe(topic, it.getQos(), it.getMessageListener());
                    log.info("当前主题 '{}' 订阅成功", topic);
                } catch (MqttException e) {
                    log.warn("当前主题 '{}' 订阅失败", topic, e);
                }
            }
        );
    }

}
